package com.haixiaoke.saas.apartment.service.impl;

import java.math.BigDecimal;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.haixiaoke.saas.apartment.domain.CalendarPrice;
import com.haixiaoke.saas.apartment.domain.HousingAllocation;
import com.haixiaoke.saas.apartment.domain.HousingPrice;
import com.haixiaoke.saas.apartment.mapper.CalendarPriceMapper;
import com.haixiaoke.saas.apartment.service.ICalendarPriceService;
import com.haixiaoke.saas.apartment.service.IHousingAllocationService;
import com.haixiaoke.saas.apartment.service.IHousingPriceService;
import com.haixiaoke.saas.common.utils.DateUtils;
import com.haixiaoke.saas.order.domain.Order;
import com.haixiaoke.saas.order.service.IOrderHousingExpensesService;
import com.haixiaoke.saas.order.service.IOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


/**
 * 价格日历Service业务层处理
 *
 * @author panda
 * @date 2024-03-29
 */
@Service
public class CalendarPriceServiceImpl implements ICalendarPriceService {
    @Autowired
    private CalendarPriceMapper calendarPriceMapper;
    @Autowired
    private IHousingAllocationService housingAllocationService;
    @Autowired
    private IHousingPriceService housingPriceService;
    @Autowired
    private IOrderHousingExpensesService orderHousingExpensesService;
    @Autowired
    private IOrderService orderService;

    /**
     * 查询价格日历
     *
     * @param id 价格日历主键
     * @return 价格日历
     */
    @Override
    public CalendarPrice selectCalendarPriceById(Long id) {
        return calendarPriceMapper.selectCalendarPriceById(id);
    }

    /**
     * 查询价格日历列表
     *
     * @param calendarPrice 价格日历
     * @return 价格日历
     */
    @Override
    public List<CalendarPrice> selectCalendarPriceList(CalendarPrice calendarPrice) {
        return calendarPriceMapper.selectCalendarPriceList(calendarPrice);
    }

    /**
     * 新增价格日历
     *
     * @param calendarPrice 价格日历
     * @return 结果
     */
    @Override
    public int insertCalendarPrice(CalendarPrice calendarPrice) {
        calendarPrice.setCreateTime(DateUtils.getNowDate());
        return calendarPriceMapper.insertCalendarPrice(calendarPrice);
    }

    /**
     * 修改价格日历
     *
     * @param calendarPrice 价格日历
     * @return 结果
     */
    @Override
    public int updateCalendarPrice(CalendarPrice calendarPrice) {
        calendarPrice.setUpdateTime(DateUtils.getNowDate());
        return calendarPriceMapper.updateCalendarPrice(calendarPrice);
    }

    /**
     * 批量删除价格日历
     *
     * @param ids 需要删除的价格日历主键
     * @return 结果
     */
    @Override
    public int deleteCalendarPriceByIds(Long[] ids) {
        return calendarPriceMapper.deleteCalendarPriceByIds(ids);
    }

    /**
     * 删除价格日历信息
     *
     * @param id 价格日历主键
     * @return 结果
     */
    @Override
    public int deleteCalendarPriceById(Long id) {
        return calendarPriceMapper.deleteCalendarPriceById(id);
    }

    @Override
    public List<HousingAllocation> selectCalendarPriceListByAllocation(HousingAllocation housingAllocation) {
        List<HousingAllocation> allocationList = housingAllocationService.selectCalendarPriceListByAllocation(housingAllocation);
        if (!allocationList.isEmpty()) {
            List<Long> allocationIds = allocationList.stream().map(HousingAllocation::getAllocationId).collect(Collectors.toList());
            List<HousingPrice> housingPriceList = housingPriceService.selectHousingPriceByAllocationIds(allocationIds);
            Map<Long, List<HousingPrice>> housingPriceListMap = housingPriceList.stream().collect(Collectors.groupingBy(HousingPrice::getAllocationId));
            LocalDate end = housingAllocation.getEndTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();// 结束日期
            for (HousingAllocation allocation : allocationList) {
                LocalDate start = housingAllocation.getStartTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();// 起始日期
                List<CalendarPrice> calendarPriceList = calendarPriceMapper.selectCalendarPriceListByTime(allocation.getAllocationId(),allocation.getHouseId(),housingAllocation.getStartTime(),housingAllocation.getEndTime(),true);
                Map<LocalDate, CalendarPrice> calendarPriceMap = calendarPriceList.stream().collect(Collectors.toMap(CalendarPrice::getCalendarTime, x ->x));
                // 循环遍历每一天
                while (!start.isAfter(end)) {
                    if (ObjectUtil.isEmpty(calendarPriceMap.get(start))) {
                        //去获取指定日期的星期几，进而获得房屋配置房费的收费标准
                        //DayOfWeek.name()获取星期的英文单词，DayOfWeek.getValue()获取数字1~7，DayOfWeek.getDisplayName(TextStyle.FULL, Locale.CHINA)后去中文星期
                        String value = String.valueOf(start.getDayOfWeek().getValue());
                        CalendarPrice calendarPrice = new CalendarPrice();
                        Optional<HousingPrice> first = housingPriceListMap.get(allocation.getAllocationId()).stream().filter(x -> x.getWeek().equals(value)).findFirst();
                        first.ifPresent(housingPrice -> calendarPrice.setCalendarPrice(housingPrice.getHousePrice()));
                        calendarPrice.setCalendarTime(start);
                        calendarPrice.setAllocationId(allocation.getAllocationId());
                        calendarPrice.setHouseId(allocation.getHouseId());
                        calendarPriceList.add(calendarPrice);
                    }
                    start = start.plusDays(1); // 增加一天
                }
                //根据日历日期
                allocation.setCalendarPriceList(calendarPriceList.stream().sorted(Comparator.comparing(CalendarPrice::getCalendarTime)).collect(Collectors.toList()));
            }
        }
        return allocationList;
    }

    @Override
    public int updateBatchCalendarPrice(CalendarPrice calendarPrice) {
        Date nowDate = DateUtils.getNowDate();
        LocalDate beginTime = calendarPrice.getStartTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();// 起始日期
        LocalDate endDate = calendarPrice.getEndTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();// 结束日期
        calendarPriceMapper.deleteCalendarPriceByTime(calendarPrice);

        List<CalendarPrice> calendarPriceList = new ArrayList<>();
        //获取房屋对应的房屋配置id
        Map<String,Map<String,Object>> map = housingAllocationService.selectAllocationIdAndHouseId(calendarPrice.getHouseIds());
        //遍历每一天
        while (!beginTime.isAfter(endDate)) {
            //批量创建数据
            for (Map.Entry<String, Map<String, Object>> entry : map.entrySet()) {
                CalendarPrice calendar = new CalendarPrice();
                calendar.setCalendarPrice(calendarPrice.getCalendarPrice());
                calendar.setCalendarTime(beginTime);
                calendar.setAllocationId((Long) entry.getValue().get("allocation_id"));
                calendar.setHouseId(entry.getKey());
                calendar.setTenantId(calendarPrice.getTenantId());
                calendar.setCreateBy(calendarPrice.getUpdateBy());
                calendar.setCreateTime(nowDate);
                calendarPriceList.add(calendar);
            }
            beginTime= beginTime.plusDays(1); // 增加一天
        }
        return calendarPriceMapper.insertBatchCalendarPrice(calendarPriceList);
    }

    @Override
    public Map<String, Map<String, Object>> selectTodayPriceByHouseIds(List<String> houseIds) {
        return calendarPriceMapper.selectTodayPriceByHouseIds(houseIds);
    }

    @Override
    public List<CalendarPrice> selectCalendarPriceListByTime(Long allocationId, String houseId, Date startTime, Date endTime,Boolean isContain) {
        return calendarPriceMapper.selectCalendarPriceListByTime(allocationId,houseId,startTime,endTime,isContain);
    }

    @Override
    public List<CalendarPrice> getPriceList(CalendarPrice calendarPrice) {
        List<HousingPrice> housingPriceList = housingPriceService.selectHousingPriceByHouseId(calendarPrice.getHouseId());
        //查询价格日历
        List<CalendarPrice> calendarPriceList = this.selectCalendarPriceListByTime(null, calendarPrice.getHouseId(), calendarPrice.getStartTime(), calendarPrice.getEndTime(), true);
        List<LocalDate> rentingTimeList = orderHousingExpensesService.selectRentingTimeByHouseIdAndTime(calendarPrice.getHouseId(),calendarPrice.getStartTime(), calendarPrice.getEndTime());
        //日历价格，key为时间
        Map<LocalDate, CalendarPrice> calendarPriceMap = null;
        if (calendarPriceList.isEmpty()) {
            calendarPriceList = new ArrayList<>();
        } else {
            calendarPriceMap = calendarPriceList.stream().collect(Collectors.toMap(CalendarPrice::getCalendarTime, x -> x));
        }
        //日历价格，key为星期1~7
        Map<String, HousingPrice> housingPriceMap = housingPriceList.stream().collect(Collectors.toMap(HousingPrice::getWeek, x -> x));
        //遍历时间，封装时间价格
        LocalDate start = calendarPrice.getStartTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();// 起始日期
        LocalDate end = calendarPrice.getEndTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();// 结束日期
        while (!start.isAfter(end)) {
            if (calendarPriceMap == null || ObjectUtil.isEmpty(calendarPriceMap.get(start))) {
                HousingPrice housingPrice = housingPriceMap.get(String.valueOf(start.getDayOfWeek().getValue()));
                CalendarPrice cp = new CalendarPrice();
                cp.setCalendarTime(start);
                cp.setCalendarPrice(housingPrice.getHousePrice());
                calendarPriceList.add(cp);
            }
            start = start.plusDays(1); // 增加一天
        }
        Order order = new Order();
        order.setHouseId(calendarPrice.getHouseId());
        for (CalendarPrice price : calendarPriceList) {
            boolean result = rentingTimeList.stream().anyMatch(time -> price.getCalendarTime().isEqual(time));
            if (result) {
                price.setReserveState("1");
            } else {
                LocalDate calendarTime = price.getCalendarTime();
                Date checkInTime = Date.from(calendarTime.atStartOfDay(ZoneId.systemDefault()).toInstant());
                order.setCheckInTime(checkInTime);
                order.setCheckOutTime(DateUtils.addDays(checkInTime, 1));
                if (orderService.checkRepeatOrder(order)) {
                    price.setReserveState("1");
                } else {
                    price.setReserveState("0");
                }
            }
        }
        //根据日历时间升序排序，日历时间为空的在前
        return calendarPriceList.stream().sorted(Comparator.comparing(CalendarPrice::getCalendarTime,Comparator.nullsFirst(Comparator.naturalOrder()))).collect(Collectors.toList());
    }
}
